package com.stegniy.primeNumbers;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class PrimeFinderCallable implements Callable<List<Long>> {

    private final long from;
    private final long to;

    public PrimeFinderCallable(final long from, final long to) {
        this.from = from;
        this.to = to;
    }

    public boolean isPrime(long number) {
        if (number <= 1)
            return false;
        for (long i = 2; i <= Math.sqrt(number); i++) {
            if (number % i == 0)
                return false;
        }
        return true;
    }

    @Override
    public List<Long> call() throws Exception {
        List<Long> primes = new ArrayList<Long>();
        for (long i = from; i <= to; i++) {
            if (isPrime(i)) {
                primes.add(i);
            }
        }
        return primes;
    }

    public static List<Long> generatePrimes(int numberOfThreads, long limitNumber) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);
        List<Future<List<Long>>> futures = new ArrayList<Future<List<Long>>>();
        for (int i = 0; i < numberOfThreads; i++) {
            final long from = i * (limitNumber/numberOfThreads);
            final long to = (i + 1) * (limitNumber/numberOfThreads) + 1;
            futures.add(executor.submit(new PrimeFinderCallable(from,to)));
        }

        executor.shutdown();

        List<Long> totalPrimes = new ArrayList<Long>();
        for (Future<List<Long>> future : futures) {
            List<Long> primes = future.get();
            totalPrimes.addAll(primes);
            }
        return totalPrimes;
    }
}
